package com.huangpeng.algorithm.concurrentProgram;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author huangpeng
 * @Title 并发编程
 * @Package
 * @Date 2021/8/17 17:08
 * @Description
 * @Version 1.0
 */
public class ConcurrentProgram {
    public static void main(String[] args) {
        poolExecutor(10);
        // 信号量同步锁
        Semaphore semaphore = new Semaphore(10);
        try {
            semaphore.acquire();

        }catch (Exception e){

        }finally {
            semaphore.release();
        }
    }

    // 创建线程池
    private static void poolExecutor(Integer size){
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5,20,2L, TimeUnit.SECONDS,new LinkedBlockingDeque<>(5));
        for (int i = 0; i < size; i++) {
            poolExecutor.execute(new DemoTask(i));
            System.out.println("poolSize:" + poolExecutor.getPoolSize());
            System.out.println("corePoolSize:" + poolExecutor.getCorePoolSize());
            System.out.println("maximumPoolSize:" + poolExecutor.getMaximumPoolSize());
            System.out.println("queue:" + poolExecutor.getQueue().size());
            System.out.println("completedTaskCount:" + poolExecutor.getCompletedTaskCount());
            System.out.println("largestPoolSize:" + poolExecutor.getLargestPoolSize());
            System.out.println("keepAliveTime:" + poolExecutor.getKeepAliveTime(TimeUnit.SECONDS));
            System.out.println("***************************************");
        }
    }


    public static void testThreadPoolExecutor(){
        //创建使用单个线程的线程池
        ExecutorService executorService1 = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            executorService1.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "正在执行任务");
                }
            });
        }
        //创建使用固定线程数的线程池
        ExecutorService es2 = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            es2.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "正在执行任务");
                }
            });
        }
        //创建一个会根据需要创建新线程的线程池
        ExecutorService es3 = Executors.newCachedThreadPool();
        for (int i = 0; i < 20; i++) {
            es3.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "正在执行任务");
                }
            });
        }
        //创建拥有固定线程数量的定时线程任务的线程池
        ScheduledExecutorService es4 = Executors.newScheduledThreadPool(2);
        System.out.println("时间：" + System.currentTimeMillis());
        for (int i = 0; i < 5; i++) {
            es4.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println("时间："+System.currentTimeMillis()+"--"+Thread.currentThread().getName() + "正在执行任务");
                }
            },3, TimeUnit.SECONDS);
        }
        //创建只有一个线程的定时线程任务的线程池
        ScheduledExecutorService es5 = Executors.newSingleThreadScheduledExecutor();
        System.out.println("时间：" + System.currentTimeMillis());
        for (int i = 0; i < 5; i++) {
            es5.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println("时间："+System.currentTimeMillis()+"--"+Thread.currentThread().getName() + "正在执行任务");
                }
            },3, TimeUnit.SECONDS);
        }
    }
}
class DemoTask implements Runnable{
    private int taskNum;
    public DemoTask(int taskNum) {
        this.taskNum = taskNum;
    }
    @Override
    public void run() {
        System.out.println("正在执行" + taskNum + "/20=");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行完毕" + taskNum + "/20=");
    }
}
